package com.springboot.mybatis.common.util;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;

/**
 * java.util.Date和SimpleDateFormatter都不是线程安全的，而LocalDate和LocalTime和最基本的String一样，
 * 是不变类型，不但线程安全，而且不能修改。而且LocalDateTime非常好用。在新的Java
 * 8中，日期和时间被明确划分为LocalDate和LocalTime，LocalDate无法包含时间，LocalTime无法包含日期。当然，LocalDateTime才能同时包含日期和时间。
 */
public class DateUtil {
    public static final String PATTERN = "yyyy-MM-dd";
    public static final String PATTERN_MONTH = "yyyy-MM";
    public static final String PATTERN_TIME = "yyyy-MM-dd HH:mm:ss";
    
    /**
     * 格式化当前日期
     * @param timestamp
     */
    public static LocalDateTime formatLocalDateTime(String time) {
        Timestamp t = Timestamp.valueOf(time);
        return t.toLocalDateTime();
    }

    public static Date Unix2Date(Long unixTime) {
        return new Date(unixTime * 1000);
    }

    public static Long Date2Unix(Date date) {
        return date.getTime() / 1000;
    }

    public static Long Date2Unix2Long(Date date) {
        return date.getTime();
    }

    public static Long Date2Unix2Long() {
        Timestamp timestamp = Timestamp.valueOf(LocalDateTime.now());//LocationDateTime 转时间戳  
        return timestamp.getTime();
    }

    public static Long Date2Unix2Long(LocalDateTime now) {
        Timestamp timestamp = Timestamp.valueOf(now);//LocationDateTime 转时间戳  
        return timestamp.getTime();
    }

    /**
     * 比较两个日期 大小
     *
     * @param nowDate 日期1
     * @param endDate 日期2
     * @return nowDate<endDate       返回true   ,   否则返回false
                    */
    public static boolean compare_date(String nowDate, String endDate) {

        DateFormat df = new SimpleDateFormat(PATTERN);
        try {
            Date dt1 = df.parse(nowDate);
            Date dt2 = df.parse(endDate);
            if (dt1.getTime() <= dt2.getTime()) {
                return true;
            } else if (dt1.getTime() > dt2.getTime()) {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 日期加一天
     *
     * @param s 要增加的日期
     * @param n 要增加的天数
     * @return String 增加n填后的日期
     */
    public static String addDay(String s, int n) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(PATTERN);

            Calendar cd = Calendar.getInstance();
            cd.setTime(sdf.parse(s));
            cd.add(Calendar.DATE, n);// 增加一天
            // cd.add(Calendar.MONTH, n);//增加一个月

            return sdf.format(cd.getTime());

        } catch (Exception e) {
            return null;
        }
    }
    
    /**
     * 格式化当前日期
     *
     * @param pattern 需要的格式
     * @return String 格式后的日期
     */
    public static String format() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(PATTERN_TIME));
    }

    /**
     * 格式化当前日期
     *
     * @param pattern 需要的格式
     * @return String 格式后的日期
     */
    public static String format(String pattern) {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 格式化当前日期
     *
     * @param date    需要格式化的时间
     * @param pattern 需要的格式
     * @return String 格式后的日期
     */
    public static String format(LocalDateTime date, String pattern) {
        return date.format(DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 格式化当前日期
     *
     * @param date    需要格式化的时间
     * @param pattern 需要的格式
     * @return String 格式后的日期
     * @throws ParseException
     */
    public static String format(String date, String pattern) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        Date d = sdf.parse(date);
        return sdf.format(d);
    }
    
    public static String format(Long date, String pattern) {
        return format(new Date(date), pattern);
    }
    
    public static String format(Date date, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }
    
    public static LocalDateTime dateFormatLocalDateTime(Date date){
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
        return localDateTime;
    }

    public static void main(String[] args) throws ParseException {
        Long d = DateUtil.Date2Unix(new Date());
        System.out.println(d);
        System.out.println(DateUtil.Unix2Date(d));
        System.out.println(DateUtil.format("2017-12-2T000", "yyyy-MM-dd"));
        System.out.println(DateUtil.Date2Unix2Long(new Date()));
        System.out.println(DateUtil.Date2Unix2Long());
    }
}
